﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace hasApopo.view
{
    public partial class myHash : Form
    {
        //atribut
        byte[] message;
        byte[] messageToCompare1;
        byte[] messageToCompare2;
        byte[] mainresult;
        String result1;
        String result2;
        long message_len;
        Boolean manual = false;
        DateTime modified = new DateTime();
        String filename;

        //methods
        public myHash()
        {
            InitializeComponent();
            result1 = "";
            result2 = "";
        }


        public void initMyHash() {
            //init vars
            algorithm.SHAalgorithm.H = new UInt32[5];
            algorithm.SHAalgorithm.K = new UInt32[4];
            algorithm.SHAalgorithm.H[0] = 1732584193;
            algorithm.SHAalgorithm.H[1] = 4023233417;
            algorithm.SHAalgorithm.H[2] = 2562383102;
            algorithm.SHAalgorithm.H[3] = 271733878;
            algorithm.SHAalgorithm.H[4] = 3285377520;
            algorithm.SHAalgorithm.K[0] = 1518500249;
            algorithm.SHAalgorithm.K[1] = 1859775393;
            algorithm.SHAalgorithm.K[2] = 2400959708;
            algorithm.SHAalgorithm.K[3] = 3395469782;

            //create array of byte from ABCDE
            algorithm.SHAalgorithm.ABCDE = new byte[20]; // 20 byte = 20 * 8 = 160bit
            algorithm.SHAalgorithm.H1234 = new byte[16]; // 16byte = 16 * 8 = 128bit
            byte[] dump;

            //create array from element 0-3 from buffer and H
            for (int i = 0; i < 4; ++i)
            {
                dump = algorithm.SHAalgorithm.breakLongIntoArrByte(algorithm.SHAalgorithm.H[i], 4);
                byte[] dump2 = algorithm.SHAalgorithm.breakLongIntoArrByte(algorithm.SHAalgorithm.K[i], 4);
                for (int j = 0; j < 4; ++j)
                {
                    algorithm.SHAalgorithm.ABCDE[i * 4 + j] = dump[j];
                    algorithm.SHAalgorithm.H1234[i * 4 + j] = dump2[j];
                }
            }

            //create last 4 array from buffer
            dump = algorithm.SHAalgorithm.breakLongIntoArrByte(algorithm.SHAalgorithm.H[4], 4);
            for (int j = 0; j < 4; ++j)
            {
                algorithm.SHAalgorithm.ABCDE[16 + j] = dump[j];
            }
        }

        /// <summary>
        /// read file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void browsefile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFile1 = new OpenFileDialog();
            openFile1.Title = "Cari nama file pesan";
            openFile1.ShowDialog();

            if (openFile1.FileName != "")
            {
                message = browseAFile(openFile1.FileName);
                browsearea.Text = openFile1.FileName;
                filename = openFile1.SafeFileName;
                StringBuilder dump = new StringBuilder();

                for (int i = 0; i < message.Length; ++i)
                {
                    /*if (message[i] == 0)
                        dump.Append(" ");
                    else */
                        dump.Append((char)message[i]);
                }

                truemessagearea.Text = dump.ToString();
                message_len = message.LongLength;
            }
        }

        /// <summary>
        /// called when we need to read a file into bytestream
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        private byte[] browseAFile(String filename)
        {
            byte[] dummymsg;
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            dummymsg = null;
            BinaryReader abc = new BinaryReader(fs);
            //cek filesizenya biar <2^64 - 1
            long filesize = new FileInfo(filename).Length;
            modified  = new FileInfo(filename).LastWriteTime;
            dummymsg = abc.ReadBytes((int)filesize);
            return dummymsg;
        }


        /// <summary>
        /// save message to file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            // prosedur yg dipanggil jika tombol ‘save as’ ditekan
            // menyimpan ke file eksternal
            if (truemessagearea.Text != "")
            {
                savebyte(StrToByteArray(truemessagearea.Text));
                truemessagearea.Text = "";
            }
            else
            {
                MessageBox.Show("No message to save");
            }
        }


        /// <summary>
        /// save any kinds of file based on its content (array of byte)
        /// </summary>
        /// <param name="pesan"></param>
        private void savebyte(byte[] pesan)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.Title = "Save As";
            saveFileDialog1.ShowDialog();

            // If the file name is not an empty string open it for saving.
            if (saveFileDialog1.FileName != "")
            {
                File.WriteAllBytes(saveFileDialog1.FileName, pesan);
            }
        }


        public static string ByteArrayToString(byte[] ba)
        {
            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in ba)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString();
        }

        // C# to convert a string to a byte array.
        public static byte[] StrToByteArray(string str)
        {
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
            return encoding.GetBytes(str);
        }

        /// <summary>
        /// get Message digest from message when button 'generate Message Digest is clicked'
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void generate_MD_Click(object sender, EventArgs e)
        {
            if ((truemessagearea.Text != "") && ((manual) || (browsearea.Text != "")))
            {
                if (manual)
                {
                    message = StrToByteArray(truemessagearea.Text);
                }

                //start generate Message digest
                initMyHash();
                byte[] tempmessage = algorithm.SHAalgorithm.insertPaddingAndMsgLength(message);
                mainresult = algorithm.SHAalgorithm.getMessageDigest(tempmessage);
                MD_result.Text = ByteArrayToString(mainresult);
            }
        }


        /// <summary>
        /// browse file 1 for comparing message digest
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void browse_file1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFile1 = new OpenFileDialog();
            openFile1.Title = "Cari nama file pesan";
            openFile1.ShowDialog();

            if (openFile1.FileName != "")
            {
                pText.Text = openFile1.FileName;
                messageToCompare1 = browseAFile(openFile1.FileName);
                messageToCompare1 = algorithm.SHAalgorithm.insertPaddingAndMsgLength(messageToCompare1);
            }
        }


        /// <summary>
        /// browse file 2 for comparing message digest
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void browse_file2_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFile1 = new OpenFileDialog();
            openFile1.Title = "Cari nama file pesan";
            openFile1.ShowDialog();

            if (openFile1.FileName != "")
            {
                qText.Text = openFile1.FileName;
                messageToCompare2 = browseAFile(openFile1.FileName);
                messageToCompare2 = algorithm.SHAalgorithm.insertPaddingAndMsgLength(messageToCompare2);
            }
        }


        /// <summary>
        /// comparing 2 files
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void compare_Click(object sender, EventArgs e)
        {
            initMyHash();
            result1 = ByteArrayToString(algorithm.SHAalgorithm.getMessageDigest(messageToCompare1));
            
            initMyHash();
            result2 = ByteArrayToString(algorithm.SHAalgorithm.getMessageDigest(messageToCompare2));

            md_file1.Text = result1;
            md_file2.Text = result2;
            if (result1.CompareTo(result2) == 0)
            {
                label5.Text = "SAME FILE";
            }
            else
            {
                label5.Text = "DIFFERENT FILE";
            }
        }


        /// <summary>
        /// save message digest
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            String[] stringarray = new String[] {
                filename,
                modified.ToString(),
                ByteArrayToString(mainresult)
            };


            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.Filter = "My Sha File (*.mysha) | *.mysha";//Bitmap Image|*.bmp|JPeg Image|*.jpg|Gif Image|*.gif";
            saveFileDialog1.Title = "Simpan hasil";
            saveFileDialog1.ShowDialog();

            // If the file name is not an empty string open it for saving.
            if (saveFileDialog1.FileName != "")
            {
                File.WriteAllLines(saveFileDialog1.FileName, stringarray);
            }
        }


        /// <summary>
        /// check box 'manual' clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void type_manual_Click(object sender, EventArgs e)
        {
            manual = !manual;
            truemessagearea.Enabled = manual;
        }

        private void myHash_Load(object sender, EventArgs e)
        {

        }

        private void saveButton_Click(object sender, EventArgs e)
        {

        }
    }
}
